load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
load("@cui//:defs.bzl", "aliases", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_doc", "rust_doc_test", "rust_library", "rust_test")
load("//crate_universe:version.bzl", "VERSION")

exports_files(
    glob([
        "src/**/*.bzl",
        "src/**/*.j2",
        "src/**/*.rs",
    ]) + [
        "Cargo.toml",
        "Cargo.lock",
        "defs.bzl",
        "docs_bzlmod.bzl",
        "docs_workspace.bzl",
    ],
    visibility = ["//visibility:public"],
)

filegroup(
    name = "bzl_srcs",
    srcs = glob(["*.bzl"]) + [
        "//crate_universe/3rdparty:bzl_srcs",
        "//crate_universe/private:bzl_srcs",
        "//crate_universe/tools:bzl_srcs",
    ],
    visibility = ["//visibility:public"],
)

bzl_library(
    name = "bzl_lib",
    srcs = [":bzl_srcs"],
    visibility = ["//visibility:public"],
    deps = ["//rust:bzl_lib"],
)

filegroup(
    name = "rust_srcs",
    srcs = glob([
        "src/**/*.bzl",
        "src/**/*.j2",
        "src/**/*.rs",
    ]),
    visibility = ["//:__subpackages__"],
)

rust_library(
    name = "cargo_bazel",
    srcs = glob(
        include = ["src/**/*.rs"],
        exclude = ["src/main.rs"],
    ),
    aliases = aliases(),
    compile_data = glob(
        include = ["src/**"],
        exclude = ["src/**/*.rs"],
    ),
    edition = "2021",
    proc_macro_deps = all_crate_deps(proc_macro = True),
    # This target embeds additional, stamping related information (see
    # https://docs.bazel.build/versions/main/user-manual.html#workspace_status
    # for more information). Set stamp = -1 to indicate that it should respect
    # the value of the --stamp comandline flag.
    stamp = -1,
    version = VERSION,
    visibility = ["//visibility:public"],
    deps = all_crate_deps(normal = True),
)

rust_binary(
    name = "cargo_bazel_bin",
    srcs = ["src/main.rs"],
    edition = "2021",
    version = VERSION,
    visibility = ["//visibility:public"],
    deps = [":cargo_bazel"],
)

alias(
    name = "bin",
    actual = ":cargo_bazel_bin",
    visibility = ["//visibility:public"],
)

rust_test(
    name = "unit_test",
    aliases = aliases(),
    crate = ":cargo_bazel",
    data = glob(["test_data/**"]) + [
        "//crate_universe/test_data/serialized_configs",
        "@rules_rust//rust/toolchain:current_cargo_files",
        "@rules_rust//rust/toolchain:current_rustc_files",
    ],
    proc_macro_deps = all_crate_deps(
        proc_macro_dev = True,
    ),
    rustc_env = {
        "CARGO": "$(rootpath @rules_rust//rust/toolchain:current_cargo_files)",
        "RUSTC": "$(rootpath @rules_rust//rust/toolchain:current_rustc_files)",
    },
    deps = [
        "@rules_rust//tools/runfiles",
    ] + all_crate_deps(
        normal_dev = True,
    ),
)

# Integration tests which invoke cargo and/or rustc as subprocesses.
rust_test(
    name = "cargo_integration_test",
    timeout = "long",
    srcs = ["tests/cargo_integration_test.rs"],
    aliases = aliases(),
    data = glob(["test_data/**"]) + [
        "//crate_universe/test_data/serialized_configs",
        "@rules_rust//rust/toolchain:current_cargo_files",
        "@rules_rust//rust/toolchain:current_rustc_files",
    ],
    edition = "2021",
    env = {
        "CARGO": "$(rootpath @rules_rust//rust/toolchain:current_cargo_files)",
        "RUSTC": "$(rootpath @rules_rust//rust/toolchain:current_rustc_files)",
    },
    proc_macro_deps = all_crate_deps(
        proc_macro_dev = True,
    ),
    rustc_env = {
        "CARGO": "$(rootpath @rules_rust//rust/toolchain:current_cargo_files)",
        "RUSTC": "$(rootpath @rules_rust//rust/toolchain:current_rustc_files)",
    },
    tags = ["requires-network"],
    deps = [
        ":cargo_bazel",
        "@rules_rust//tools/runfiles",
    ] + all_crate_deps(
        normal = True,
    ),
)

rust_test(
    name = "versions_test",
    srcs = ["tests/version_test.rs"],
    data = [
        "Cargo.toml",
        "version.bzl",
    ],
    edition = "2021",
    rustc_env = {
        "CARGO_TOML": "$(rootpath :Cargo.toml)",
        "VERSION_BZL": "$(rootpath :version.bzl)",
    },
)

rust_doc(
    name = "rustdoc",
    crate = ":cargo_bazel",
    rustdoc_flags = [
        "--cap-lints=warn",
        "--document-private-items",
        "--allow=rustdoc::private_intra_doc_links",
    ],
    visibility = ["//visibility:public"],
)

rust_doc_test(
    name = "rustdoc_test",
    crate = ":cargo_bazel",
)
